<script setup>
import { ref, defineProps, defineExpose, watch } from 'vue'
import { ElMessage } from 'element-plus'

const props = defineProps({
  table: {
    type: String,
    default: ''
  },
  header: {
    type: String,
    default: ''
  }
})

const formItems = ref([])
const ruleForm = ref({})
const rules = ref({})
const ruleFromRef = ref(null)

import { readTableFormApi, getSourceItemsApi, readDataApi } from "@/service/db";
import BanquetMenu from "@/components/banquet-menu.vue";
import CarItem from "@/components/car-item.vue";

// 获取数据源数据
const getSourceItems = async (field) => {
  const res = await getSourceItemsApi({table: field.DataSource})
  // 将res.data = [{id:'', title: ''}] 转换成 [{label: '', value: ''}]
  field.Options = res.data.map(item => {
    return {
      label: item.title,
      value: item.id
    }
  });
}

// 设置字段默认值
const setFieldDefaultValue = (field) => {
  // 根据字段类型设置适当的默认值
  switch(field.FormItemType) {
    case 'menu':
      // 确保返回一个数组
      if (!field.Default) return [];
      if (typeof field.Default === 'string' && field.Default.trim() === '') return [];
      try {
        // 尝试解析字符串为JSON (如果是)
        if (typeof field.Default === 'string') {
          return JSON.parse(field.Default);
        }
      } catch (e) {
        return [];
      }
      return Array.isArray(field.Default) ? field.Default : [];
    case 'checkbox':
      if (!field.Default) return [];
      return Array.isArray(field.Default) ? field.Default : [field.Default];
    case 'switch':
      return field.Default === '1' || field.Default === true;
    case 'number':
      return field.Default !== undefined ? Number(field.Default) : 0;
    case 'date':
      return field.Default || '';
    case 'car':
      return field.Default || [];
    default:
      return field.Default || '';
  }
}

// 获取表单配置
const getFormConfig = (formData) => {
  readTableFormApi({table: props.table}).then(({data}) => {
    formItems.value = data
    // 将formItems转换为ruleForm
    formItems.value.forEach(item => {
        ruleForm.value[item.Field] = setFieldDefaultValue(item);
        
        // 获取数据源数据
        if (item.DataSource) {
          getSourceItems(item)
        }

        // 设置验证规则
        if (item.Required) {
          rules.value[item.Field] = [{
            required: true,
            message: item.Placeholder || `请输入${item.Title}`,
            trigger: ['blur', 'change']
          }]
        }
        
        // 如果有自定义验证规则
        if (item.Validate) {
          if (!rules.value[item.Field]) {
            rules.value[item.Field] = []
          }
          
          // 解析验证规则字符串
          try {
            // Validate 为正则表达式字符串如'Validate: /^[0-9]*$/'，需要转换为正则表达式对象
            const reg = eval(item.Validate)
            rules.value[item.Field].push({
              pattern: reg,
              message: `请输入正确的${item.Title}`,
              trigger: ['blur', 'change']
            })
            
          } catch (e) {
            console.warn(`Invalid validation rule for field ${item.Field}:`, item.Validate)
          }
        }
    })

    // 将formData的值赋值给ruleForm
    if (!formData) {
      return
    }

    // 如果formData.id有值，则读取数据
    if (formData.id) {
      readDataApi({table: props.table, id: formData.id}).then(({code,data,msg}) => {
        if (code !== 200) {
          ElMessage.error(msg)
          return
        }
        
        // 将data的值赋值给ruleForm
        Object.keys(data).forEach(key => {
          ruleForm.value[key] = data[key]
        })
      })
    }
  })
}

// 生成表单
const generateForm = (formData) => {
  getFormConfig(formData)
}

// 获取表单数据
const getFormData = () => {
  return ruleForm.value
}

// 验证表单并返回结果
const validateForm = () => {
  return new Promise((resolve) => {
    // 如果表单引用不存在，直接返回空对象
    if (!ruleFromRef.value) {
      resolve(ruleForm.value);
      return;
    }
    
    // 清除表单之前的验证结果
    ruleFromRef.value.clearValidate();
    
    // 对表单进行验证
    ruleFromRef.value.validate((valid) => {
      if (valid) {
        resolve(ruleForm.value);
      } else {
        resolve(false);
      }
    });
  });
}

// 监听 table 变化
watch(() => props.table, (newVal) => {
  if (newVal) {
    getFormConfig(null);
  }
}, { immediate: true });

defineExpose({
    generateForm,
    getFormData,
    validateForm
})
</script>

<template>
    
    <el-form ref="ruleFromRef" :model="ruleForm" :rules="rules" label-width="120px" label-position="top" :validate-on-rule-change="false">
        <el-form-item v-for="item in formItems" :key="item.Field" :label="item.Title" :prop="item.Field">
          <el-input v-if="item.FormItemType === 'input'" v-model="ruleForm[item.Field]" :placeholder="item.Placeholder"></el-input>
    
          <el-select v-else-if="item.FormItemType === 'select'" v-model="ruleForm[item.Field]" :placeholder="item.Placeholder">
            <el-option v-for="option in item.Options" :key="option.value" :label="option.label" :value="option.value"></el-option>
          </el-select>
          
          <el-radio-group v-else-if="item.FormItemType === 'radio'" v-model="ruleForm[item.Field]">
            <el-radio v-for="option in item.Options" :key="option.value" :value="option.value">{{ option.label }}</el-radio>
          </el-radio-group>
          
          <el-checkbox-group v-else-if="item.FormItemType === 'checkbox'" v-model="ruleForm[item.Field]">
            <el-checkbox v-for="option in item.Options" :key="option.value" :value="option.value">{{ option.label }}</el-checkbox>
          </el-checkbox-group>
          
          <el-date-picker v-else-if="item.FormItemType === 'date'" v-model="ruleForm[item.Field]" type="date" value-format="YYYY-MM-DD" :placeholder="item.Placeholder"></el-date-picker>
            
          <el-input v-else-if="item.FormItemType === 'textarea'" type="textarea" v-model="ruleForm[item.Field]" 
            :placeholder="item.Placeholder"></el-input>
            
          <el-switch v-else-if="item.FormItemType === 'switch'" v-model="ruleForm[item.Field]"></el-switch>
          
          <el-slider v-else-if="item.FormItemType === 'slider'" v-model="ruleForm[item.Field]"></el-slider>
          
          <upload-image v-else-if="item.FormItemType === 'upload'" v-model="ruleForm[item.Field]"></upload-image>

          <banquet-menu v-else-if="item.FormItemType === 'menu'" v-model="ruleForm[item.Field]"></banquet-menu>

          <car-item v-else-if="item.FormItemType == 'car'" v-model="ruleForm[item.Field]"></car-item>
        </el-form-item>
    </el-form>

</template>


